<?php
// TODO: Make this not hideous ;-)

/*
 * This is a simple viewer, from this will be developed a full blown feature rich ;-) viewer
 * For the moment though it's a one page mash of rubbish that exists purely to show that the
 * library is working the way it should.
 * 
 * There's no reason why this liitle app wouldn't be useful, but this is not the focus of the development.
 * Rather it's the library that's important (for the moment anyway).
 * 
 * So, don't start ripping this page apart and wondering why such a lovely object oriented
 * library would have such a mess for a front end... it's intended to be this way; I am not spending
 * time sorting out the viewer application when I could be working on the library instead...
 *
 * That doesn't mean that this isn't useful.  it serves to direct the library structure, to make this
 * application as simple as possible... it's only a front end after all.  Plus we do use this in our own
 * team to examine our own database structures.
 * 
 */

// Functionality
// TODO: Sort out the default button so it isn't disconnect
// TODO: Improve the print view
// TODO: Add an option for 'number of degrees of separation' on the click to load stuff
// TODO: Add a 'no tables found' message and a bit of validation on the inputs?
 
// Structure
// TODO: Move the CSS out to a separate file
// TODO: Move the HTML out to a template file

ini_set( 'include_path', '../;.' );

require_once( 'include_package.php' );

include_package( 'Datasources'  , true );
include_package( 'DatabaseModel', true );
include_package( 'Renderers'    , true );

Session::Start();

$sStartsWith               = '';
$sEndsWith                 = '';
$sSelectedTableName        = '';
$nDegreesOfSeparation      = '';
$sTableReferencesTableName = '';
$sOracleUsername           = '';
$sOraclePassword           = '';
$sOracleInstance           = '';
$sTableInformation         = '';
$sImageHtml                = '';
$sUserAction               = '';

$sHtmlConfigHtml           = '';
$sDotConfigHtml            = '';
$sOracleErrorText          = '';

if ( isset( $_REQUEST['Submit'] ) ) {
	$sUserAction = $_REQUEST['Submit'];
}

$sOracleUsername           = array_key_exists( 'OracleUsername', $_REQUEST )           ? $_REQUEST['OracleUsername']:'';
$sOraclePassword           = array_key_exists( 'OraclePassword', $_REQUEST )           ? $_REQUEST['OraclePassword']:'';
$sOracleInstance           = array_key_exists( 'OracleInstance', $_REQUEST )           ? $_REQUEST['OracleInstance']:'';
$sStartsWith               = array_key_exists( 'StartsWith', $_REQUEST )               ? $_REQUEST['StartsWith']:'';
$sEndsWith                 = array_key_exists( 'EndsWith', $_REQUEST )                 ? $_REQUEST['EndsWith']:'';
$sSelectedTableName        = array_key_exists( 'SelectedTableName', $_REQUEST )        ? $_REQUEST['SelectedTableName']:'';
$nDegreesOfSeparation      = array_key_exists( 'DegreesOfSeparation', $_REQUEST )      ? $_REQUEST['DegreesOfSeparation']:'';
$sTableReferencesTableName = array_key_exists( 'TableReferencesTableName', $_REQUEST ) ? $_REQUEST['TableReferencesTableName']:'';

// Build the database model

$oDatasource = new NullDatasource();
if ( $sOracleUsername || $sOraclePassword || $sOracleInstance ) {
	$oDatasource = new OracleDatasource( $sOracleUsername, $sOraclePassword, $sOracleInstance );
	if ( $oDatasource->Errored() ) {
		$sOracleErrorText = $oDatasource->GetLastError();
	}
}

$oDatasource = new CachedDatasource( $oDatasource );

if ( $sUserAction == 'Connect' ) {
	$oDatasource->ClearCache();
}

if ( $sUserAction == 'Disconnect' ) {
	$oDatasource->ClearCache();
	$oDatasource->Disconnect();	
}

$bConnected  = $oDatasource->IsConnected();

if ( $bConnected && $sUserAction == 'Get Tables' ) {
	$oFilter = false;
	
	if ( $sStartsWith && $sEndsWith ) {
		$oFilter = new Filter_And( new Filter_TableStartsWith( $sStartsWith ), new Filter_TableEndsWith( $sEndsWith ) );
	} elseif ( $sStartsWith ) {
		$oFilter = new Filter_TableStartsWith( $sStartsWith );
	} elseif ( $sEndsWith ) {
		$oFilter = new Filter_TableEndsWith( $sEndsWith );
	} elseif ( $sSelectedTableName ) {
		$oFilter = new Filter_TableReferencesTable( $oDatasource, $sSelectedTableName, 0 );
	} elseif ( $sTableReferencesTableName ) {
		if ( is_numeric( $nDegreesOfSeparation ) ) {
			$nDegreesOfSeparation = (int)$nDegreesOfSeparation;
		} else {
			$nDegreesOfSeparation = '';
		}
		$oFilter = new Filter_TableReferencesTable( $oDatasource, $sTableReferencesTableName, $nDegreesOfSeparation );
	}
	
	if ( $oFilter ) {
		$oDatasource = new Filtration( $oDatasource, $oFilter );
	}
	
	$oFactory = new DatabaseFactory( $oDatasource );
	$oDatabase = $oFactory->ConstructDatabase();
	
	$sBaseUrl = 'viewer.php?Submit=Get%20Tables&OracleUsername='.$sOracleUsername.'&OraclePassword='.$sOraclePassword.'&OracleInstance='.$sOracleInstance.'&SelectedTableName=';
	
	
	$oDotConfig = new DotRendererConfiguration();
	$oDotConfig->SetProperty( 'BaseTableLinkUrl', $sBaseUrl );
	//This won't live here, it's just a bit of mucking about...
	// $sDotConfigHtml = $oDotConfig->GetHtml();

	
	//
	// Generate the image and its map
	//
	$oImageGenerator = new DotImageGenerator( DotDatabaseRenderer::Render( $oDotConfig, $oDatabase ), 'c:/progra~1/att/graphviz/bin/' );
	$sImage = $oImageGenerator->GenerateImageInSession( 'Gif', uniqid( rand(), true ) );
	$sImageMap = $oImageGenerator->GenerateImage( 'CMap' );

	if ( $sImage && $sImageMap ) {
		$sImageHtml	= '<img src="../SessionImageLoader.php?ImageId='.$sImage.'" alt="ER Diagram" ISMAP USEMAP="#map" /><map name="map">'.$sImageMap.'</map>';
	}

	//
	// Generate the HTML documentation
	//
	$oHtmlConfig = new HtmlRendererConfiguration();
	$oHtmlConfig->SetProperty( 'ShowTables', false );
	$oHtmlConfig->SetProperty( 'IncludeTableLinksToFilteredTables', true );
	$oHtmlConfig->SetProperty( 'BaseTableLinkUrl', $sBaseUrl );
	$sTableInformation = HtmlDatabaseRenderer::Render( $oHtmlConfig, $oDatabase );
	//This won't live here, it's just a bit of mucking about...
	//$sHtmlConfigHtml = $oHtmlConfig->GetHtml();
}

if ( $bConnected ) {
	$sSubmitValue = 'Disconnect';
} else {
	$sSubmitValue = 'Connect';
}

if ( $sOracleErrorText ) {
	$sOracleErrorText = HtmlTag::P ( $sOracleErrorText, 'ErrorText' );
}

$sOracleConnectionHtml = HtmlTag::H( 1, 'Database Connection' )
				  	   . HtmlTag::InputBox( 'OracleUsername', $sOracleUsername, 'Username:', !$bConnected )
					   . HtmlTag::InputBox( 'OraclePassword', $sOraclePassword, 'Password:', !$bConnected )
					   . HtmlTag::InputBox( 'OracleInstance', $sOracleInstance, 'Instance:', !$bConnected )
					   . $sOracleErrorText
					   . HtmlTag::SubmitButton( 'Submit', $sSubmitValue ) . HtmlTag::Br();
$sFiltersHtml = null;
if ( $bConnected ) {
	$sFiltersHtml = HtmlTag::H( 1, 'Table Filters' )
				  . HtmlTag::InputBox( 'StartsWith'              , $sStartsWith              , 'Name starts with:'      )
				  . HtmlTag::InputBox( 'EndsWith'                , $sEndsWith                , 'Name ends with:'        )
				  . HtmlTag::P( 'OR' )
				  . HtmlTag::InputBox( 'SelectedTableName'       , $sSelectedTableName       , 'Named:'                 )
				  . HtmlTag::P( 'OR' )
				  . HtmlTag::InputBox( 'TableReferencesTableName', $sTableReferencesTableName, 'Table references:'      )
				  . HtmlTag::InputBox( 'DegreesOfSeparation'     , $nDegreesOfSeparation     , 'Degrees of Separation:' )
				  . HtmlTag::SubmitButton( 'Submit', 'Get Tables' ) . HtmlTag::Br();
}
// Damn layout problems...
//<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/transitional.dtd">

?>
<html>
	<head>
		<title>P-dd Simple Viewer</title>
		<style type="text/css">
			#LeftBar {
				display: block;
				width: 240px;
			}
			#MainContent {
				position: absolute;
				top: 0px;
				left: 250px;
				width: 100%;
			}
			form {
				border: 1px solid grey;
				border-top: none;
			}
			body {
				font-size: 8pt;
				font-family: arial;	
				padding: 0px;
				margin: 2px;
				padding-left: 5px;
				padding-right: 12px;
			}
			.SubContent h1 {
				font-size: 12pt;
				font-family: arial;
				padding-left: 5px;
			}
			.SubContent h2 {
				font-size: 10pt;
				font-family: arial;
				border-bottom: 1px solid black;
				padding-left: 5px;
			}
			.SubContent h3 {
				font-size: 8pt;
				font-family: arial;
				border-bottom: 1px solid grey;
				padding-left: 5px;
			}
			.SubContent td {
				font-size: 8pt;	
				padding: 3px;
			}
			.SubContent table {
				margin-left: 5px;
			}
			.SubContent .TableColumns .TitleRow td {
				font-weight: bold;
				font-family: arial;
				font-size: 10pt;
			}
			img {
				border: none;	
			}
			.ErrorText {
				color: red;
				font-weight: bold;	
			}
			#Entry h1 {
				font-size: 10pt;	
				font-family: arial;
				padding-left: 10px;
				border-bottom: 1px solid grey;
				border-top: 1px solid grey;
				background-color: lightgrey;
				margin-top: 0px;
				padding-top: 3px;
			}
			#Entry label{
				float: left;
				width: 110px;
				font-weight: bold;
				padding-left: 5px;
			}
			#Entry p {
				padding-left: 10px;
			}
			#Entry input, #Entry textarea {
				width: 120px;
				margin-bottom: 5px;
				height: 20px;
			}
			#Entry .SubmitButton {
				height: 22px;
				margin: 5px;
			}
			#Entry br{
				clear: left;
			}
		</style>
		
		<style type="text/css" media="print">
			#LeftBar {
				display: none;
			}
			#MainContent {
				position:absolute;
				top:0px;
				left:0px;
				width: 100%;
				border: none;
			}
			.SubContent {
				border: none;	
			}
		</style>
		
	</head>
	<body>
		<div id="Leftbar">
			<div id="Entry">
				<form action="viewer.php" method="POST">
					<?=$sOracleConnectionHtml?>
					<?=$sFiltersHtml?>
					<?=$sHtmlConfigHtml?>
					<?=$sDotConfigHtml?>
				</form>
			</div>
		</div>
		<div id="MainContent">
			<div class="SubContent"><?=$sImageHtml?></div>
			<div class="SubContent"><?=$sTableInformation?></div>
		</div>
	</body>
</html>